#include "Application.h"

void mini_engine::Application::run()
{
    initWindow();
    initVulkan();
    mainLoop();
    cleanUp();
}

/**
 * 初始化窗口
 */
void mini_engine::Application::initWindow()
{
    InitWindow::getInitWindow()->createWindow();
}

void mini_engine::Application::initVulkan()
{
    Instance::getInstance()->createInstance();
    WindowSurface::getWindowSurface()->createWindowSurface();
    PhysicalDevice::getPhysicalDevice()->pickUpPhyiscalDevice();
    LogicalDevice::getLogicalDevice()->createLogicalDevice();
    SwapChain::getSwapChain()->createSwapChain();
    ImageViews::getImageViews()->createImageViews();
    RenderPass::getRenderPass()->createRenderPass();
    GraphicsPipeline::getGraphicsPipeline()->createGraphicsPipeline();
    Framebuffers::getFramebuffers()->createFramebuffers();
    Command::getCommand()->createCommandPool();
    Model::getModel()->createVertexBuffer();
    Command::getCommand()->createCommandBuffer();
    SyncObjects::getSyncObjects()->createSyncObjects();
}

void mini_engine::Application::mainLoop()
{
    while (!glfwWindowShouldClose(InitWindow::window))
    {
        glfwPollEvents();
        DrawFrame::drawFrame();
    }
    vkDeviceWaitIdle(LogicalDevice::logicalDevice);
}

void mini_engine::Application::cleanUp()
{
    vkDestroySemaphore(LogicalDevice::logicalDevice, SyncObjects::renderFinishedSemaphore, nullptr);
    vkDestroySemaphore(LogicalDevice::logicalDevice, SyncObjects::imageAvailableSemaphore, nullptr);
    vkDestroyFence(LogicalDevice::logicalDevice, SyncObjects::inFlightFence, nullptr);
    vkDestroyCommandPool(LogicalDevice::logicalDevice, Command::commandPool, nullptr);
    for (auto framebuffer : Framebuffers::swapChainFramebuffers)
    {
        vkDestroyFramebuffer(LogicalDevice::logicalDevice, framebuffer, nullptr);
    }
    vkDestroyPipeline(LogicalDevice::logicalDevice, GraphicsPipeline::graphicsPipeline, nullptr);
    vkDestroyPipelineLayout(LogicalDevice::logicalDevice, GraphicsPipeline::pipelineLayout, nullptr);
    vkDestroyRenderPass(LogicalDevice::logicalDevice, RenderPass::renderPass, nullptr);

    vkDestroyBuffer(LogicalDevice::logicalDevice, Model::vertexBuffer, nullptr);
    vkFreeMemory(LogicalDevice::logicalDevice, Model::vertexBufferMemory, nullptr);

    for (auto imageView : ImageViews::swapChainImageViews)
    {
        vkDestroyImageView(LogicalDevice::logicalDevice, imageView, nullptr);
    }

    vkDestroySwapchainKHR(LogicalDevice::logicalDevice, SwapChain::swapChain, nullptr);
    vkDestroyDevice(LogicalDevice::logicalDevice, nullptr);

    vkDestroySurfaceKHR(Instance::instance, WindowSurface::surface, nullptr);
    vkDestroyInstance(Instance::instance, nullptr);

    glfwDestroyWindow(InitWindow::window);

    glfwTerminate();
}

mini_engine::Application::Application()
{
}

mini_engine::Application::~Application()
{
}
